//
//  Keyboarder.swift
//  ASW
//
//  Created by zhuxuhong on 2020/12/3.
//

import UIKit

public enum Keyboarder {
    static let notifications = [
        UIResponder.keyboardWillShowNotification,
        UIResponder.keyboardDidShowNotification,
        UIResponder.keyboardWillHideNotification,
        UIResponder.keyboardDidHideNotification,
        UIResponder.keyboardWillChangeFrameNotification,
        UIResponder.keyboardDidChangeFrameNotification
    ]
    
    public static func remove(for target: NSObject) {
        Notifier.remove(notifications, for: target)
    }
    
    public static func observe(on target: NSObject, _ handler: @escaping BlockT<Keyboard>) {
        Notifier.observe(
            notifications,
            on: target
        ) {
            guard
                let info = $0.userInfo,
                let index = notifications.firstIndex(of: $0.name),
                let status = Keyboard.Status(rawValue: index) else {
                return
            }
            var rect: CGRect = .zero
            var duration: CGFloat = 0
            var curve: Int = 0
            if let v = info[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect {
                rect = v
            }
            if let v = info[UIResponder.keyboardAnimationDurationUserInfoKey] as? CGFloat {
                duration = v
            }
            if let v = info[UIResponder.keyboardAnimationCurveUserInfoKey] as? Int {
                curve = v
            }
            handler(.init(frame: rect, duration: duration, curve: curve, status: status))
        }
    }
}

extension Keyboarder {
    public struct Keyboard {
        public enum Status: Int {
            case unknown = -1
            case willShow
            case didShow
            case willHide
            case didHide
            case willChangeFrame
            case didChangeFrame
        }
        public let frame: CGRect!
        public let duration: CGFloat!
        public let curve: Int!
        public let status: Status!
        
        public init(frame: CGRect, duration: CGFloat, curve: Int, status: Status){
            self.frame = frame
            self.duration = duration
            self.curve = curve
            self.status = status
        }
    }
}
